struct ECSB2Exact <: ECSB2OptimisationAlgorithm 
  solver
end

function optimise_linear_sqrtlinear(instance::CombinatorialInstance, ::ECSB2Exact, 
                                    linear::Dict{T, Float64}, sqrtlinear::Dict{T, Float64}, epsilon::Float64, d::Int, verbose::Int) where T
  error("The exact solver for ECSB2 has not been fine-tuned for this kind of problems: " * string(typeof(instance)))
end

function optimise_linear_sqrtlinear(instance::PerfectBipartiteMatching, algo::ECSB2Exact, 
                                    linear::Dict{T, Float64}, sqrtlinear::Dict{T, Float64}, epsilon::Float64, d::Int, verbose::Int; with_trace::Bool=false) where T
  n = size(instance.reward, 1)
  x = Convex.Variable(n, n, Convex.Positive(), :Bin)
  p = Convex.maximize(sum(linear[(i, j)] * x[i, j] for (i, j) in keys(linear)) + sqrt(sum(sqrtlinear[(i, j)] * x[i, j] for (i, j) in keys(sqrtlinear))))
  for i in 1:n # Left nodes. 
    p.constraints += sum(x[i, j] for j in 1:n) <= 1
  end
  for j in 1:n # Right nodes. 
    p.constraints += sum(x[i, j] for i in 1:n) <= 1
  end
  t0 = now()
  Convex.solve!(p, algo.solver)
  t1 = now()
  
  x = x.value
  if with_trace
    runDetails = ECSB2Details()
    runDetails.bestLinearObjective = sum(linear[(i, j)] * x[i, j] for (i, j) in keys(linear)) + sum(sqrtlinear[(i, j)] * x[i, j] for (i, j) in keys(sqrtlinear))
    runDetails.bestNonlinearObjective = p.optval
    runDetails.solverTimes = Float64[(t1 - t0).value]
    return [ind2sub(x, v) for v in find(x .>= .5)], runDetails # TODO: ind2sub deprecated in Julia 0.7. 
  else 
    return [ind2sub(x, v) for v in find(x .>= .5)] # TODO: ind2sub deprecated in Julia 0.7. 
    # https://github.com/JuliaLang/julia/pull/24715#issuecomment-348323494
  end
end